//
// Created by james on 2022/1/22.
//

#include "bitmat.h"

void bitmapToMat2(JNIEnv *env, jobject& bitmap, Mat& mat, jboolean needUnPremultiplyAlpha){
    AndroidBitmapInfo* bitmapInfo;
    void* pixels;
    try {
        CV_Assert(AndroidBitmap_getInfo(env,bitmap,bitmapInfo) >= 0);
        CV_Assert(bitmapInfo->format == ANDROID_BITMAP_FORMAT_RGBA_8888 || bitmapInfo->format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(AndroidBitmap_lockPixels(env,bitmap,&pixels) >= 0);
        CV_Assert(pixels);
        mat.create(bitmapInfo->height,bitmapInfo->width,CV_8UC4);
        if (bitmapInfo->format == ANDROID_BITMAP_FORMAT_RGBA_8888){
            Mat tmp(bitmapInfo->height,bitmapInfo->width,CV_8UC4,pixels);
            if (needUnPremultiplyAlpha){
                cvtColor(tmp,mat,COLOR_mRGBA2RGBA);
            } else{
                tmp.copyTo(mat);
            }
        } else{
            Mat tmp(bitmapInfo->height,bitmapInfo->width,CV_8UC2,pixels);
            tmp.copyTo(mat);
        }
        AndroidBitmap_unlockPixels(env,bitmap);
    }catch (...){
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}");
    }
}
void matToBitmap2(JNIEnv *env, jobject& bitmap, Mat& mat, jboolean needUnPremultiplyAlpha){
    AndroidBitmapInfo* bitmapInfo;
    void* pixels;
    try {
        CV_Assert(AndroidBitmap_getInfo(env,bitmap,bitmapInfo) >= 0);
        CV_Assert(bitmapInfo->format == ANDROID_BITMAP_FORMAT_RGBA_8888 || bitmapInfo->format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(mat.dims == 2 && bitmapInfo->height == mat.rows && bitmapInfo->width == mat.cols);
        CV_Assert(mat.type() == CV_8UC1 || mat.type() == CV_8UC3 || mat.type() == CV_8UC4);
        CV_Assert(AndroidBitmap_lockPixels(env,bitmap,&pixels) >= 0);
        CV_Assert(pixels);
        if (bitmapInfo->format == ANDROID_BITMAP_FORMAT_RGBA_8888){
            Mat tmp(bitmapInfo->height,bitmapInfo->width,CV_8UC4,pixels);
            if (mat.type() == CV_8UC1){
                cvtColor(mat,tmp,COLOR_GRAY2RGBA);
            } else if (mat.type() == CV_8UC3){
                cvtColor(mat,tmp,COLOR_RGB2RGBA);
            } else if (mat.type() == CV_8UC4){
                cvtColor(mat,tmp,COLOR_RGBA2mRGBA);
            }
        } else{
            Mat tmp(bitmapInfo->height,bitmapInfo->width,CV_8UC2,pixels);
            if (mat.type() == CV_8UC1){
                cvtColor(mat, tmp, COLOR_GRAY2BGR565);
            } else if (mat.type() == CV_8UC3){
                cvtColor(mat, tmp, COLOR_RGB2BGR565);
            } else if (mat.type() == CV_8UC4){
                cvtColor(mat, tmp, COLOR_RGBA2BGR565);
            }
        }
    }catch (...){
        jclass je = env->FindClass("java/lang/Exception");
        env->ThrowNew(je, "Unknown exception in JNI code {nBitmapToMat}");
    }

}

void bitmat::BitmapToMat(JNIEnv *env, jobject &bitmap, Mat &mat) {
    bitmapToMat2(env, bitmap, mat, false);
}

void bitmat::MatToBitmap(JNIEnv *env, jobject &bitmap, Mat &mat) {
    matToBitmap2(env, bitmap, mat, false);
}
